﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace CacheData
{
    public class CacheDb : RedisHelper
    {
        private static readonly string redisConnectionString;
        private static readonly int redisCacheTime;
        private static readonly int redisMode;
        static CacheDb()
        {
            var builder = new ConfigurationBuilder()
               .SetBasePath(Directory.GetCurrentDirectory())
               .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
               .AddEnvironmentVariables()
               .Build();
            redisConnectionString = builder["RedisConnectionString"];
            redisCacheTime = int.Parse(builder["RedisCacheTime"]);
            redisMode = int.Parse(builder["RedisMode"]);
            CSRedis.CSRedisClient csredis = null;
            switch (redisMode)
            {
                //Single machine redis
                case 0:
                    csredis = new CSRedis.CSRedisClient(redisConnectionString);
                    break;
                //Redis Sentinel(哨兵模式)
                case 1:
                    string sentinelStr = builder["SentinelIP"];
                    string[] sentinelArray = sentinelStr.Split(';');
                    csredis = new CSRedis.CSRedisClient(redisConnectionString, sentinelArray);
                    break;
                //Redis Cluster(分布式)
                case 2:
                    csredis = new CSRedis.CSRedisClient(redisConnectionString);
                    break;
                default:
                    break;
            }
            if(csredis != null)
            {
                CacheDb.Initialization(csredis);
            }
            else
            {
                throw new Exception($"not support redis mode: {redisMode}");
            }
        }

        public static async Task<T> GetDataUseCache<T>(string key,Func<T> callback,int timeout = 0)
        {
            if (timeout == 0) 
                timeout = redisCacheTime;
            T result;
            var json = await CacheDb.GetAsync(key);
            string noneStr = "{{none}}";
            if (noneStr.Equals("json"))
                return default(T);
            if (string.IsNullOrEmpty(json))
            {
                result = callback();
                if (result != null)
                    json = JsonConvert.SerializeObject(result);
                else
                    json = noneStr;
                await CacheDb.SetAsync(key, json, timeout);
            }
            else
            {
                result = JsonConvert.DeserializeObject<T>(json);
            }
            return result;
        }
    }
}
